home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / WINSOCK.PAK / DLGLISTN.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  6KB  |  165 lines

  1. /*-----------------------------------------------------------------------*\
  2. | OWLSock Demo For Windows v1.0                                           |
  3. --------------------------------------------------------------------------|
  4. | Written By:  Paul Pedriana                                              |
  5. | Date:        May 7, 1995.                                               |
  6. | Copyright:   Copyright (c) 1995 by Paul Pedriana.  All Rights Reserved. |
  7. | UserID(s):   70541,3223                                                 |
  8. |              70541.3223@compuserve.com                                  |
  9. --------------------------------------------------------------------------|
  10. | This OWLSock demo is an application that demonstrates some features     |
  11. | of OWLSock.  It uses only asynchronous (non-blocking) Winsock calls,    |
  12. | and uses OWLSock socket 'external' notification rather than internal    |
  13. | notification.  External notification is the way most Winsock apps do    |
  14. | FD_XXX notifications; see the OWLSock docs for more info.               |
  15. --------------------------------------------------------------------------|
  16. | Notes on this module:                                                   |
  17. |    This module acts like a server and listens for stream socket         |
  18. | connections on the specified port.  If a connection is made, this       |
  19. | dialog spawns a stream dialog box just like the one used to make        |
  20. | connections.                                                            |
  21. \*-----------------------------------------------------------------------*/
  22.  
  23. #include <owl/pch.h>
  24. #if !defined(OWL_WINSOCK_H)
  25. # include <owl/winsock.h>
  26. #endif
  27. #include <stdlib.h>   //For atoi() call.
  28. #include "dlglstn.h"
  29. #include "dlgstrm.h"
  30.  
  31. //********************************************************************************************
  32. DEFINE_RESPONSE_TABLE1(DlgListen, TDialog)
  33.   EV_CHILD_NOTIFY(IDC_BTN_LISTEN, BN_CLICKED, CmBtnListen),
  34.   EV_MESSAGE(MSG_SOCKET_NOTIFY, DoSocketNotification),
  35. END_RESPONSE_TABLE;
  36.  
  37. DlgListen::DlgListen(TWindow *parent, TResId resId, TModule *module)
  38. :
  39.   TDialog(parent, resId, module)
  40. {
  41.   TINetSocketAddress ourSocketAddress(0, INADDR_ANY);  //same as 'ourSocketAddress()'
  42.  
  43.   myPresentState = nIdle;
  44.   myStreamSocket = new TStreamSocket(ourSocketAddress);
  45.   myStreamSocket->SetNotificationWindow(this); //redirect socket FD_XXX notifications to us.
  46. }
  47.  
  48. DlgListen::~DlgListen()
  49. {
  50.   delete myStreamSocket;
  51. }
  52.  
  53. void DlgListen::SetupWindow()
  54. {
  55.    editPort        = new TEdit(this, IDC_EDIT_PORT,      8);
  56.    staticStatus     = new TStatic(this, IDC_STATIC_STATUS, 32);
  57.    buttonListen     = new TButton(this, IDC_BTN_LISTEN);
  58.    TDialog::SetupWindow();
  59. }
  60.  
  61. short DlgListen::SpawnChildConnection()
  62. {
  63.   TStreamSocket newStreamSocket;  //construct an empty StreamSocket object.
  64.   newStreamSocket.SetSaveSocketOnDelete();  //Don't close the socket on deletion, b/c we're giving it to someone else.
  65.  
  66.   int nError = myStreamSocket->Accept(newStreamSocket); //Accept() will completely fix up nStreamSocket.
  67.   if (nError == WINSOCK_ERROR){ //could also say: 'if (nError){'
  68.     MessageBox(TSocketError(myStreamSocket->GetLastError()).AppendError("Error on Accept()."), "Error", MB_OK);
  69.     return 0;
  70.   }
  71.   DlgSendStream* demoDlgSendStream = new DlgSendStream(GetApplication()->GetMainWindow());
  72.   demoDlgSendStream->Create();
  73.   demoDlgSendStream->ConnectWithThis(newStreamSocket);
  74.   return 1;
  75. }
  76.  
  77.  
  78. LRESULT DlgListen::DoSocketNotification(WPARAM, LPARAM lParam)
  79. {
  80.   int  nEvent = (int)WSAGETSELECTEVENT(lParam);
  81.   int  nError = (int)WSAGETSELECTERROR(lParam);
  82.  
  83.   if (nEvent == FD_ACCEPT){
  84.     if (nError)
  85.       MessageBox(TSocketError(nError).AppendError("Error on receipt of FD_ACCEPT."), "Error", MB_OK);
  86.     else
  87.       SpawnChildConnection();
  88.   }
  89.   else{
  90.     MessageBox("Listening socket received a non-FD_ACCEPT FD_ notification", "Suspicious...", MB_OK);
  91.   }
  92.   return 1;
  93. }
  94.  
  95.  
  96.  
  97. void DlgListen::CmBtnListen()
  98. {
  99.   ushort nPort;
  100.   char   szPort[8];
  101.   int    nError;
  102.  
  103.   if (myPresentState == nIdle){
  104.     nError = myStreamSocket->CreateSocket(); //similar to 'socket()'
  105.     if (nError == WINSOCK_ERROR){ //could also say 'if (nError){'
  106.       MessageBox(TSocketError(myStreamSocket->GetLastError()).AppendError("Error on CreateSocket()"), "Error", MB_OK);
  107.       GoToIdleState();
  108.       return;
  109.     }
  110.     myStreamSocket->StartAcceptNotification();  //similar to 'WSAAsyncSelect()'
  111.     myStreamSocket->SetNotificationWindow(this); //redirect socket FD_XXX notifications to us.
  112.  
  113.     editPort->GetWindowText(szPort, 7);
  114.     nPort = TWinSock::Dll()->htons((u_short)atoi(szPort));
  115.     nError = myStreamSocket->BindSocket(TINetSocketAddress(nPort, INADDR_ANY)); //similar to 'bind()'
  116.     if (nError == WINSOCK_ERROR){ //could also say 'if (nError){'
  117.       MessageBox(TSocketError(myStreamSocket->GetLastError()).AppendError("Error on BindSocket()"), "Error", MB_OK);
  118.       GoToIdleState();
  119.       return;
  120.     }
  121.     nError = myStreamSocket->Listen();
  122.     if (nError == WINSOCK_ERROR){ //could also say 'if (nError){'
  123.       MessageBox(TSocketError(myStreamSocket->GetLastError()).AppendError("Error on Listen()"), "Error", MB_OK);
  124.       GoToIdleState();
  125.       return;
  126.     }
  127.     GoToListeningState();
  128.   }
  129.  
  130.   else { //myPresentState == nListening
  131.     // I don't know of any way to stop listening other than simply closing the socket and
  132.     //  then recreating it so we can re-listen on it later.
  133.     // On the other hand, it is very uncommon for an application to do what this demo
  134.     //  application is doing--allowing you to randomly listen to any port you want to
  135.     //  and stop and go at any time.
  136.     GoToIdleState();
  137.   }
  138. }
  139.  
  140. void DlgListen::CmOk()
  141. {
  142.   if (myPresentState != nIdle)
  143.     CmBtnListen();  //This will return everything to normal and idle.
  144.   TDialog::CmOk();
  145. }
  146.  
  147.  
  148. void DlgListen::GoToIdleState()
  149. {
  150.   staticStatus->SetWindowText("Status: Idle");
  151.   buttonListen->SetWindowText("Listen");
  152.   editPort->SetReadOnly(FALSE); //Make the port editable.
  153.   myPresentState = nIdle;
  154.   myStreamSocket->CloseSocket();
  155. }
  156.  
  157.  
  158. void DlgListen::GoToListeningState()
  159. {
  160.   staticStatus->SetWindowText("Status: Listening");
  161.   buttonListen->SetWindowText("Stop");
  162.   editPort->SetReadOnly(TRUE); //Make the port un-editable.
  163.   myPresentState = nListening;
  164. }
  165.